import { PdfJs, Store, StoreHandler } from "../../core";

import PrintProgress from "./PrintProgress";
import PrintStatus from "./PrintStatus";
import PrintZone from "./PrintZone";
import StoreProps from "./StoreProps";
import { FC, useEffect, useState } from "react";

interface PrintContainerProps {
  doc: PdfJs.PdfDocument;
  pageHeight: number;
  pageWidth: number;
  rotation: number;
  store: Store<StoreProps>;
}

const PrintContainer: FC<PrintContainerProps> = ({
  doc,
  pageHeight,
  pageWidth,
  rotation,
  store,
}) => {
  const [printStatus, setPrintStatus] = useState(PrintStatus.Inactive);
  const [numLoadedPagesForPrint, setNumLoadedPagesForPrint] = useState(0);

  const cancelPrinting = (): void => {
    setNumLoadedPagesForPrint(0);
    setPrintStatus(PrintStatus.Inactive);
  };

  const handlePrintStatus: StoreHandler<PrintStatus> = (status: PrintStatus) =>
    setPrintStatus(status);

  const onLoadPage = () => {
    const total = numLoadedPagesForPrint + 1;
    if (total <= doc.numPages) {
      setNumLoadedPagesForPrint(total);
      total === doc.numPages && setPrintStatus(PrintStatus.Ready);
    }
  };

  useEffect(() => {
    store.subscribe("printStatus", handlePrintStatus);
    return () => {
      store.unsubscribe("printStatus", handlePrintStatus);
    };
  }, []);

  return (
    <>
      {printStatus === PrintStatus.Preparing && (
        <PrintProgress
          numLoadedPages={numLoadedPagesForPrint}
          numPages={doc.numPages}
          onCancel={cancelPrinting}
        />
      )}
      {(printStatus === PrintStatus.Preparing ||
        printStatus === PrintStatus.Ready) &&
        numLoadedPagesForPrint <= doc.numPages && (
          <PrintZone
            doc={doc}
            numLoadedPages={numLoadedPagesForPrint}
            pageHeight={pageHeight}
            pageWidth={pageWidth}
            printStatus={printStatus}
            rotation={rotation}
            onCancel={cancelPrinting}
            onLoad={onLoadPage}
          />
        )}
    </>
  );
};

export default PrintContainer;
